package com.zxy.study.ui.widget;

import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.os.Build;
import androidx.annotation.RequiresApi;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ScrollView;

import com.zxy.study.R;


/*
 *  @项目名：  study
 *  @包名：    com.zxy.study.ui.widget
 *  @文件名:   HeadZoomScrollView
 *  @创建者:   zhangxy
 *  @创建时间:  2018/6/20 15:54
 *  @描述：    顶部图片可放大缩小的
 */
public class HeadZoomScrollView extends ScrollView {

    private static final String TAG = HeadZoomScrollView.class.getSimpleName();
    /**
     * 缩放控件的原始宽度
     */
    private int mZoomViewWidth;
    /**
     * 缩放控件的原始高度
     */
    private int mZoomViewHeight;

    private float mScaleTimes = 2;

    /**
     * 缩放的View
     */
    private View mZoomView;

    /**
     * 缩放比例系数,数值越大，滑动时缩放越大
     */
    private float mScaleRatio = 0.6f;
    /**
     * 最大缩放系数
     */
    private float mMaxScaleRatio = 1.4f;

    /**
     * 回弹系数，数值越大，回弹越慢
     */
    private float mReplyRatio = 0.3f;

    /**
     * 标识是否可以进行缩放
     */
    private boolean mScaling = false;

    /**
     * 开始缩放时的y坐标
     */
    private float mScaleStartY;

    public HeadZoomScrollView(Context context) {
        super(context);
        init(null);
    }

    public HeadZoomScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context.obtainStyledAttributes(attrs, R.styleable.HeadZoomScrollView));
    }

    public HeadZoomScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context.obtainStyledAttributes(attrs, R.styleable.HeadZoomScrollView, defStyleAttr, -1));
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public HeadZoomScrollView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init(context.obtainStyledAttributes(attrs, R.styleable.HeadZoomScrollView, defStyleAttr, defStyleRes));
    }

    /**
     * 解析自定义属性
     *
     * @param ta
     */
    private void init(TypedArray ta) {
        if (ta == null) return;

        for (int i = 0; i < ta.getIndexCount(); i++) {
            int attrId = ta.getIndex(i);
            switch (attrId) {
                case R.styleable.HeadZoomScrollView_zoom_scale_ratio:
                    mScaleRatio = ta.getFloat(attrId, 0.6f);
                    break;
                case R.styleable.HeadZoomScrollView_zoom_max_scale_ratio:
                    mMaxScaleRatio = ta.getFloat(attrId, 1.4f);
                    break;
                case R.styleable.HeadZoomScrollView_zoom_reply_ratio:
                    mScaleRatio = ta.getFloat(attrId, 0.3f);
                    break;
                default:
                    break;
            }
        }
        ta.recycle();
    }

    public void setZoomView(View zoomView) {
        mZoomView = zoomView;
    }

    public void setScaleRatio(float scaleRatio) {
        mScaleRatio = scaleRatio;
    }

    public void setMaxScaleRatio(float maxScaleRatio) {
        mMaxScaleRatio = maxScaleRatio;
    }

    public void setReplyRatio(float replyRatio) {
        mReplyRatio = replyRatio;
    }

    public View getZoomView() {
        return mZoomView;
    }

    public float getScaleRatio() {
        return mScaleRatio;
    }

    public float getMaxScaleRatio() {
        return mMaxScaleRatio;
    }

    public float getReplyRatio() {
        return mReplyRatio;
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        if (mZoomViewWidth <= 0 || mZoomViewHeight <= 0) {
            mZoomViewWidth = mZoomView.getMeasuredWidth();
            mZoomViewHeight = mZoomView.getMeasuredHeight();
        }
        if (mZoomView == null || mZoomViewWidth <= 0 || mZoomViewHeight <= 0) {
            return super.onTouchEvent(ev);
        }

        switch (ev.getAction()) {
            case MotionEvent.ACTION_MOVE:
                if (!mScaling) {
                    int scrollY = getScrollY();
                    if (scrollY == 0) {
                        mScaleStartY = ev.getY();
                        mScaling = true;
                    } else {
                        break;
                    }
                }
                float dy = ev.getY() - mScaleStartY;
                if (dy < 0) {
                    mScaling = false;
                    break;
                }
                float distance = dy * mScaleRatio;
                setViewZoom(distance);

                return true;
            case MotionEvent.ACTION_UP:
                mScaling = false;
                replyView();
                break;
            default:
                break;
        }
        return super.onTouchEvent(ev);
    }

    /**
     * 设置 mZoomView 缩放
     *
     * @param s 缩放的大小
     */
    private void setViewZoom(float s) {
        float newZoomWidth = mZoomViewWidth + s;
        float scale = newZoomWidth / (mZoomViewWidth * 1.0f);

        if (scale > mMaxScaleRatio) return;
        ViewGroup.LayoutParams layoutParams = mZoomView.getLayoutParams();
        layoutParams.width = (int) newZoomWidth;
        layoutParams.height = (int) (mZoomViewHeight * scale);
        // 设置控件水平居中
//        ((MarginLayoutParams) layoutParams).setMargins(-(layoutParams.width - mZoomViewWidth) / 2, 0, 0, 0);
        mZoomView.setLayoutParams(layoutParams);
    }

    /**
     * 回弹mZoomView到原来的大小
     */
    private void replyView() {
        int distance = mZoomView.getMeasuredWidth() - mZoomViewWidth;
        ValueAnimator valueAnimator = ObjectAnimator.ofFloat(distance, 0).setDuration((long) (distance *
                mReplyRatio));
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                setViewZoom((Float) animation.getAnimatedValue());
            }
        });
        valueAnimator.start();
    }

}
